﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Threading;

namespace Pixysoft.Framework.Noebe.Core
{
    class AbstractProxyConnection : IDbConnection
    {
        private IDbConnection realConnection = null;



        private string connectionId;

        private ProxyConnectionStatus status = ProxyConnectionStatus.Available;

        protected readonly ReaderWriterLock locker = new ReaderWriterLock();


        public AbstractProxyConnection(string connectionId, IDbConnection connection)
        {
            this.connectionId = connectionId;

            this.realConnection = connection;

            this.status = ProxyConnectionStatus.Available;
        }

        //----------- MANUAL DEFINED ----------------------------------

        public string ConnectionId
        {
            get
            {
                return this.connectionId;
            }
        }

        public void SetRemoved()
        {
            this.status = ProxyConnectionStatus.Removed;
        }

        public bool IsRemoved()
        {
            return this.status == ProxyConnectionStatus.Removed;
        }

        public bool IsDisposed()
        {
            locker.AcquireReaderLock(Timeout.Infinite);

            try
            {
                return this.status == ProxyConnectionStatus.Disposed;
            }
            finally
            {
                locker.ReleaseReaderLock();
            }
        }

        public IDbConnection GetConnection()
        {
            return this;
        }

        //----------- OVERRIDE ----------------------------------

        public virtual void Close()
        {
            this.realConnection.Close();
        }

        public virtual void Dispose()
        {
            locker.AcquireWriterLock(Timeout.Infinite);

            try
            {
                this.status = ProxyConnectionStatus.Disposed;

                this.realConnection.Dispose();

                this.realConnection = null;
            }
            finally
            {
                locker.ReleaseWriterLock();
            }
        }

        //----------- NOT CHANGED ----------------------------------

        public void Open()
        {
            this.realConnection.Open();
        }

        public IDbCommand CreateCommand()
        {
            return this.realConnection.CreateCommand();
        }

        public IDbTransaction BeginTransaction(IsolationLevel il)
        {
            return this.realConnection.BeginTransaction(il);
        }

        public IDbTransaction BeginTransaction()
        {
            return this.realConnection.BeginTransaction();
        }

        public void ChangeDatabase(string databaseName)
        {
            realConnection.ChangeDatabase(databaseName);
        }

        public int ConnectionTimeout
        {
            get { return realConnection.ConnectionTimeout; }
        }

        public string Database
        {
            get { return realConnection.Database; }
        }

        public string ConnectionString
        {
            get
            {
                return realConnection.ConnectionString;
            }
            set
            {
                this.realConnection.ConnectionString = value;
            }
        }

        public ConnectionState State
        {
            get { return realConnection.State; }
        }
    }

    enum ProxyConnectionStatus
    {
        Available,
        Removed,
        Disposed,
    }
}
